'use strict'
// 导入electron模块，创建窗口app,  BrowserWindow
// 引入 Electron 的核心模块，用于创建应用、窗口、IPC 通信等。
import {app, protocol, BrowserWindow, ipcMain } from 'electron'
import { Menu } from 'electron'
// 是一个用于 Vue.js 和 Electron 的插件。
import {createProtocol} from 'vue-cli-plugin-electron-builder/lib'
// 用于安装开发工具，方便调试。
import installExtension, {VUEJS_DEVTOOLS} from 'electron-devtools-installer'


// //express服务器
// const express = require('express');
// const http = require('http');
// const webSocket = require('ws');


//openVpn文件配置的读取与修改
const fs = require('fs');
const axios = require('axios');

// 子进程和网络相关模块
// child_process 模块用于创建和管理子进程。
const {spawn} = require('child_process')

// electron-updater 用于处理应用的自动更新。
const { autoUpdater } = require('electron-updater')
const isDevelopment = process.env.NODE_ENV !== 'production';

// net 模块用于创建 TCP 服务器和客户端。
const net = require('net')
const {exec} = require('child_process');

// path 模块处理文件路径。
const path = require('path');

//监控器的
// const isDev = require('electron-is-dev');


// iconv-lite 用于处理字符编码。
const iconvLite = require('iconv-lite');

// node-wifi 用于管理 Wi-Fi 连接。
const wifi = require('node-wifi');

// 路径和变量定义
// 定义了一些路径和变量。com0comPath 和 n2nPath 指向特定资源路径。client 是一个 TCP Socket 实例，用于与服务器通信。
const com0comPath = path.join(__dirname, '..', 'resources', 'com0com');
// const n2nPath = path.join(__dirname, '..', 'resources', 'n2n-v.3.0.0');

//定义变量接收openVPN；
const openVpnPath = path.join(__dirname, '..', 'resources', 'OpenVPN');
//定义一个变量接收config
const configPath = path.join(__dirname,'..', 'resources', 'OpenVPN' , 'config');

let client = new net.Socket();
let isSocketClosed = true;
let devClient;
let devClientIP;
// let n2nStatus = 2;
let openStatus = 2;//(12.5fm)

// Wi-Fi 初始化和协议注册
wifi.init()
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
    {scheme: 'app', privileges: {secure: true, standard: true}}
])

// 创建窗口
async function createWindow() {
    //当app启动之后执行窗口创建等操作
    // Create the browser window.（创建窗口）
    const win = new BrowserWindow({
        width: 1400,
        height: 800,
        minWidth: 650,
        minHeight: 800,
        webPreferences: {

            // Use pluginOptions.nodeIntegration, leave this alone
            // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info

            preload: path.join(__dirname, 'preload.js'),

            nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
            contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
        }
    });
    // 窗口事件处理;在窗口关闭时，防止默认行为，强制关闭相关进程和套接字连接，然后销毁窗口。
    // 在当前窗口中加载指定界面让它显示具体的内容
    // 通过on 来进行事件的监听，进行回调
    // win.on('close', (e) => {
    //     e.preventDefault();
    //     exec("taskkill /IM com2tcp.exe /F", ()=> {
    //         console.log("already kill")
    //         if (devClient && !devClient.destroyed) {
    //             devClient.removeAllListeners();
    //             devClient.destroy();
    //         }
    //         closeN2n()
    //         if (client && !client.destroyed) {
    //             client.removeAllListeners();
    //             client.destroy();
    //         }
    //         win.destroy();
    //     });
    // })

    //open的12.5fm
    win.on('close', (e) => {
        e.preventDefault();
        exec("taskkill /IM com2tcp.exe /F", ()=> {
            console.log("already kill")
            if (devClient && !devClient.destroyed) {
                devClient.removeAllListeners();
                devClient.destroy();
            }
            closeOpenVPN()
            if (client && !client.destroyed) {
                client.removeAllListeners();
                client.destroy();
            }
            win.destroy();
        });
    })




    // 加载应用程序内容
    // 设置应用程序菜单为 null，避免显示默认菜单。
// 根据开发模式加载不同的 URL，如果是在开发模式下则加载开发服务器的 URL，否则加载本地的 index.html。
    Menu.setApplicationMenu(null);
    if (process.env.WEBPACK_DEV_SERVER_URL) {
        // Load the url of the dev server if in development mode
        await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
        if (!process.env.IS_TEST) win.webContents.openDevTools()
    } else {
        createProtocol('app')
        // Load the index.html when not in development
        win.loadURL('app://./index.html')
    }
    // 监听 IPC 事件，处理从渲染进程发送过来的数据，并作出相应的处理。
    ipcMain.on('send-settings', (event, data) => {
        console.log('receive request')
        let result;
        if (devClient && !devClient.destroyed) {
            result = sentData(data, devClient);
        } else {
            event.reply('server-not-connect', 'devClient');
            if (client.destroyed) event.reply('server-not-connect', 'client');
            if (!isSocketClosed && client.destroyed) result = sentData(data, client);
        }
        if (!result) event.reply('server-not-connect','client');

    });
    // ipcMain.on('close-n2n', () => {
    //     closeN2n()
    // });

    //12.5fm
    ipcMain.on('close-open',()=>{
        closeOpenVPN()
    })

    ipcMain.on('reconnect-server', async (event) => {
        console.log("----------try reconnecting----------")
        if (client && !client.destroyed) {
            client.removeAllListeners();
            client.destroy();
        }
        let success = '';
        setTimeout(()=> {
            console.log("this is success")
            if (!success) {
                event.reply('connect-callback', '1-0');
                client.removeAllListeners();
                client.destroy();
            }
        }, 5000);
        success = await createConnection(event);
        if (!success) event.reply('connect-callback', '1-0');
        else event.reply('connect-callback', '0-2');
    });
    // ipcMain.on('run-n2n', (event, room) => {
    //     runN2N(room, event);
    // });

    //接收openVpn//12.5fm
    ipcMain.on('open-vpn', (event, room) => {
        runOpenVPN(room, event);
    });

    ipcMain.on('conn-remote', (event, ip) => {
        exec("taskkill /IM com2tcp.exe /F");
        if (devClient && !devClient.destroyed) {
            devClient.removeAllListeners();
            devClient.destroy();
        }
        setTimeout(() => {
            testConnect(event, ip);
        }, 1500);
    });
    ipcMain.on('disconnect-remote', (event) => {
        console.log('------killing com2tcp------')
        exec("taskkill /IM com2tcp.exe /F");
        console.log('---------- disconnect remote ----------')
        if (devClient && !devClient.destroyed) {
            devClient.removeAllListeners();
            devClient.destroy();
        }
        event.reply('connect-callback', '0-3');
    });
    ipcMain.on('serial-port-mapping', (event, data) => {
        const jsonData = JSON.parse(data);
        console.log("----------try connect remote device----------")
        setTimeout(() => {
            connectRemote(jsonData, event);
        }, 500)
    })
    ipcMain.on('ping-device', (event, ip) => {
        pingDevice(ip, event);
    });
    ipcMain.on('request-ip', (event) => {
        event.reply('send-ip', devClientIP)
    });
    ipcMain.on('start-update', (event, downloadUrl) => {
        console.log(downloadUrl)
        autoUpdater.setFeedURL(downloadUrl);
        autoUpdater.checkForUpdates();
        autoUpdater.downloadUpdate();
    })
    ipcMain.handle('get-wifi-networks', async () => {
        return new Promise((resolve, reject) => {
            wifi.scan((err, networks) => {
                if (err) reject(err);
                else resolve(networks);
            });
        });
    });
    ipcMain.handle('ping-server', async (event) => {
        const test = {
            "cmd": 255
        };
        const data = JSON.stringify(test);
        sentData(data, client);
        event.reply('ping-already');
    })
    autoUpdater.on('download-progress', (progressObj) => {
        const { percent } = progressObj;
        console.log(percent)
        win.webContents.send('update_download_progress', percent); // 发送进度给渲染进程
    });
    // 监听下载完成事件
    autoUpdater.on('update-downloaded', () => {
        autoUpdater.quitAndInstall();
    });
   
    //12.9(修改文件fm)
    ipcMain.on('modify-config', async (event) => {
        try {
          await modifyConfigFile(); // 调用修改文件的函数
          event.reply('config-modified', '配置文件已成功修改'); // 发送成功消息给渲染进程
        } catch (error) {
          event.reply('config-modified', `修改失败: ${error.message}`); // 发送失败消息
        }
      });


}

// 应用程序的生命周期管理;监听所有窗口关闭事件，如果不是 macOS，则退出应用。
// Quit when all windows are closed.
app.on('window-all-closed', () => {
    // On macOS it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

//激活应用程序;在 macOS 中，如果没有窗口打开，重新创建一个窗口。
app.on('activate', () => {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
// 应用启动后初始化;应用准备就绪后，安装开发工具并创建窗口。
app.on('ready', async () => {
    if (isDevelopment && !process.env.IS_TEST) {
        // Install Vue Devtools
        try {
            await installExtension(VUEJS_DEVTOOLS)
        } catch (e) {
            console.error('Vue Devtools failed to install:', e.toString())
        }
    }
    await createWindow()

    const curWindow = BrowserWindow.getFocusedWindow()
    if (curWindow) {
        setTimeout(() => {
            curWindow.webContents.send('run-n2n');
        }, 20000)
    }
})

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
    if (process.platform === 'win32') {
        process.on('message', (data) => {
            if (data === 'graceful-exit') {
                app.quit()
            }
        })
    } else {
        process.on('SIGTERM', () => {
            app.quit()
        })
    }
}

// 定义读取和修改openVPN中client.ovpn配置文件的方法(12/6fm)
async function modifyConfigFile() {
    const configFilePath = path.join(__dirname, '..', 'resources', 'OpenVPN', 'config', 'client.ovpn');
  
    try {
      console.log('配置文件路径:', configFilePath);
  
      // 获取串口信息（异步）
      const response = await axios.get('http://118.31.36.254:7887/123456-abv');
      const serialPort = response.data.serialPort;  // 处理返回的 JSON 数据，确保获取正确的字段
  
      // 读取配置文件内容（同步读取）
      let fileContent = fs.readFileSync(configFilePath, 'utf8');
      console.log('原始文件内容:', fileContent); // 打印原始内容
  
      // 替换配置中的 IP 和路径
      fileContent = fileContent.replace(/remote 192\.168\.100\.6 1194/g, `remote 118.31.36.254 ${serialPort}`);
      fileContent = fileContent
        .replace(/ca D:\/Project\/config-kits\/resources\/OpenVPN\/config\/ca\.crt/g, `ca ${serialPort}/ca.crt`)
        .replace(/cert D:\/Project\/config-kits\/resources\/OpenVPN\/config\/client\.crt/g, `cert ${serialPort}/client.crt`)
        .replace(/key D:\/Project\/config-kits\/resources\/OpenVPN\/config\/client\.key/g, `key ${serialPort}/client.key`);
  
      console.log('修改后的文件内容:', fileContent); // 打印修改后的内容
  
      // 写入修改后的内容到文件
      fs.writeFileSync(configFilePath, fileContent, 'utf8');
      console.log('配置文件已成功修改');
  
      // 读取并确认写入成功
      const updatedContent = fs.readFileSync(configFilePath, 'utf8');
      console.log('更新后的文件内容:', updatedContent); // 确认写入成功
  
    } catch (error) {
      // 详细的错误处理，打印错误信息
      console.error('修改配置文件时出错:', error.message);
      if (error.response) {
        // 请求失败时，打印出 HTTP 错误信息
        console.error('HTTP 错误:', error.response.status, error.response.data);
      }
    }
  }
// // 在应用准备好后调用方法
// app.whenReady().then(() => {
//   modifyConfigFile();
// });



// 连接和数据处理逻辑;createConnection 函数用于创建 TCP 连接，监听来自服务器的数据。
function createConnection(event) {
    return new Promise((resolve, reject) => {
        let buffer = ''; // 用于缓存接收到的数据
        let expectedLength = 0; // 预期的长度
        let lengthPrefixReceived = false; // 标记是否已接收到长度前缀
        client = new net.Socket();
        client.connect(3322, '192.168.100.16', () => {
            console.log(111221)
            console.log('Successfully connected');
            resolve(true);
            isSocketClosed = false;
        });
        client.on('data', (data) => {
            // console.log(`receive data \n${data}`)
            console.log('Received data:', data.toString());
      


            buffer += data.toString();
            if (!lengthPrefixReceived) {
                // 检查是否包含长度信息
                const lengthMatch = buffer.match(/---####0\.1####---(\d+)/);
                if (lengthMatch) {
                    expectedLength = parseInt(lengthMatch[1], 10); // 提取数据长度
                    lengthPrefixReceived = true; // 已接收到长度前缀
                    console.log(`Expected length (in bytes): ${expectedLength}`);
                }
            }
            // 检查是否已接收到第二部分数据
            if (lengthPrefixReceived) {
                const index = buffer.indexOf('---####0.2####---');
                if (index !== -1) {
                    // 获取第二部分数据
                    const completeData = buffer.slice(index + '---####0.2####---'.length);
                    const completeDataLength = Buffer.byteLength(completeData, 'utf8'); // 计算接收到的数据长度（字节数）

                    if (completeDataLength >= expectedLength) {
                        // 数据完整，处理数据
                        const jsonData = completeData.slice(0, expectedLength); // 获取完整的JSON数据
                        buffer = buffer.slice(index + '---####0.2####---'.length + expectedLength); // 清理缓冲区
                        console.log(`Received complete data: ${jsonData}`);
                        event.reply('server-data-callback', jsonData);

                        // 重置状态以等待下一个数据包
                        expectedLength = 0;
                        lengthPrefixReceived = false;
                    }
                }
            }
            // event.reply('server-data-callback', data.toString())
        });

        client.on('timeout', () => {
            console.log('Connection timed out');
            client.destroy();
            reject(new Error('Connection timed out')); // 连接超时
        });
        client.on('error', (error) => {
            console.log(`receive error \n${error}`)
            resolve(false);
            isSocketClosed = true;
        });
        client.on('close', () => {
            console.log('close successfully')
            isSocketClosed = true;
        });
    });
}




// 数据发送函数;sentData 函数用于将数据发送到指定的 Socket，前面添加头部信息以指示数据长度。
function sentData(data, sender) {
    console.log(55555)
    let head1 = "---####0.1####---";
    let head2 = "---####0.2####---";
    if (!sender.destroyed) {
        console.log(66666)
        console.log(`transporting data ${data.toString()}`);
        const size = Buffer.byteLength(data, 'utf8');
        head1 = head1 + String(size).padStart(4, '0');
        head2 = head2 + data;
        sender.write(head1);
        console.log(`already sent\n${head1}`);
        sender.write(head2);
        console.log(`already sent\n${head2}`)
        return true;
    }
    return false;
}

// 运行n2n
function runN2N(room, event) {
    if (n2nStatus === 0) {
        event.reply('connect-callback', '0-0');
        return;
    } else if (n2nStatus === 1) {
        event.reply('connect-callback', '0-1');
        return;
    }
    //n2n的命令
    const n2nCommand = `${n2nPath}\\edge.exe`;
    const n2nArgs = ['-c', room, '-l', '118.31.36.254:8024', '-a', 'static:10.1.1.253/8', '-z1'];
    const n2nProcess = spawn(n2nCommand, n2nArgs);
    n2nStatus = 0;
    n2nProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${iconvLite.decode(data, 'GBK')}`)
        event.reply('connect-callback', iconvLite.decode(data, 'GBK'));
        let output = data.toString()
        const match = output.match(/\[OK].*/);
        if (match) {
            n2nStatus = 1;
            console.log('连接成功:', match[0]);
            event.sender.send('n2n-success', `连接成功${match[0]}`);
        }
    });

    n2nProcess.stderr.on('data', (data) => {
        event.reply('connect-callback', iconvLite.decode(data, 'GBK'));
        const output = data.toString();
        if (output === 'No Windows tap devices found, did you run tapinstall.exe?') {
            closeN2n();
        }
        console.error(`stderr: ${data}`);
    });

// 监听子进程结束事件
    n2nProcess.on('close', (code) => {
        n2nStatus = 2;
        console.log(`n2n process exited with code ${code}`);
        if (code !== 0) {
            event.sender.send('n2n-failed', `n2n process exited with code ${code}`)
        }
    });
}

//openVPN//12.5fm
function runOpenVPN(room,event){
    if (openStatus === 0) {
        event.reply('connect-callback', '0-0');
        return;
    } else if (openStatus === 1) {
        event.reply('connect-callback', '0-1');
        return;
    }
       //openVPN的
       const OpenVPNCommand = `${openVpnPath}\\bin/openvpn.exe`;
       const OpenVpnArgs =  ['--config',`${configPath}\\client.ovpn`];
       const OpenProcess = spawn(OpenVPNCommand, OpenVpnArgs);
       openStatus = 0;
       //如果是数据
    OpenProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${iconvLite.decode(data, 'GBK')}`)
        event.reply('connect-callback', iconvLite.decode(data, 'GBK'));
        let output = data.toString()
        const match = output.match(/\[OK].*/);
        if (match) {
            openStatus = 1;
            console.log('连接成功:', match[0]);
            event.sender.send('open-success', `连接成功${match[0]}`);
        }
    });
       //如果失败的话
    OpenProcess.stderr.on('data', (data) => {
        event.reply('connect-callback', iconvLite.decode(data, 'GBK'));
        const output = data.toString();
        if (output === 'No Windows tap devices found, did you run tapinstall.exe?') {
            closeOpenVPN();
        }
        console.error(`stderr: ${data}`);
    });

   // 监听子进程结束事件
    OpenProcess.on('close', (code) => {
        openStatus = 2;
        console.log(`open process exited with code ${code}`);
        if (code !== 0) {
            event.sender.send('open-failed', `n2n process exited with code ${code}`)
        }
    });
}

// 连接串口映射
function connectRemote(jsonData, event) {
    // .\ponticulus.exe --com \\.\ABC 115200 8 n 1 --ignoreDSR --1on1 --tcp --host 10.166.162.10 8889
    // \com2tcp.exe --ignore-dsr \\.\ETECON11 10.1.1.27 8888
    const ip = jsonData.ip;
    devClientIP = ip;
    for (const index in jsonData.portArray) {
        if (jsonData.portArray[index].remotePort === 8888) jsonData.portArray[index].port = 'ETECON11';
        else if (jsonData.portArray[index].remotePort === 8889) jsonData.portArray[index].port = 'ETECON12';
        else if (jsonData.portArray[index].remotePort === 8890) jsonData.portArray[index].port = 'ETECON13';
    }
    const portArray = jsonData.portArray;
    console.log(jsonData)
    const command = `${com0comPath}\\com2tcp.exe`;
    portArray.forEach((portInfo) => {
        const args = [
            '--ignore-dsr', `\\\\.\\${portInfo.port}`,
            ip,
            portInfo.remotePort
        ]
        const connProcess = spawn(command, args);
        connProcess.stdout.on('data', (data) => {
            console.log(`stdout: ${iconvLite.decode(data, 'GBK')}`)
            event.reply('conn-result', `stdout: ${iconvLite.decode(data, 'GBK')}`)
        });
        connProcess.stderr.on('data', (data) => {
            console.error(`stderr: ${data}`);
            event.reply('conn-result', `stderr: ${data}`)
            devClientIP = '';
        });
        // 监听子进程结束事件
        connProcess.on('close', (code) => {
            console.log(`com2tcp process exited with code ${code}`);
            if (code === 2) event.reply('conn-result', 'failed to connect');
            event.reply('conn-result', `${ip} exited with code ${code}`)
            devClientIP = '';
            const d = "{\n" +
                "\t\"response\": 229\n" +
                "}";
            event.reply('server-data-callback', d);
        });
    })

    setTimeout(() => {
        const data = {
            "cmd": 248
        }
        sentData(JSON.stringify(data), devClient);
        console.log('---------- ask for result ----------')
    }, 3000);
}

// 关闭n2n;释放资源。
// function closeN2n() {
//     exec('taskkill /IM edge.exe /F');
//     n2nStatus = 2;
// }

//12.5fm
function closeOpenVPN(){
    exec('taskkill /IM edge.exe /F');
    openStatus = 2;
}

// 测试串口是否映射成功
function testConnect(event, ip) {
    const id = setTimeout(() => {
        devClient.removeAllListeners();
        devClient.destroy();
        event.reply('conn-result', 'failed to connect');
    }, 7000);
    return new Promise((resolve, reject) => {
        let buffer = ''; // 用于缓存接收到的数据
        let expectedLength = 0; // 预期的长度
        let lengthPrefixReceived = false; // 标记是否已接收到长度前缀
        devClient = new net.Socket();
        devClient.connect(3321, ip, () => {
       
            console.log(`${ip} 已建立tcp连接`);
            resolve(true);
            const requestPortSet = {
                "cmd": 247
            };
            sentData(JSON.stringify(requestPortSet), devClient);
        });
        devClient.on('data', (data) => {
            console.log(`receive data from remote device \n${data}`)
            buffer += data.toString();
            if (!lengthPrefixReceived) {
                // 检查是否包含长度信息
                const lengthMatch = buffer.match(/---####0\.1####---(\d+)/);
                if (lengthMatch) {
                    expectedLength = parseInt(lengthMatch[1], 10); // 提取数据长度
                    lengthPrefixReceived = true; // 已接收到长度前缀
                    console.log(`Expected length (in bytes): ${expectedLength}`);
                }
            }
            // 检查是否已接收到第二部分数据
            if (lengthPrefixReceived) {
                const index = buffer.indexOf('---####0.2####---');
                if (index !== -1) {
                    // 获取第二部分数据
                    const completeData = buffer.slice(index + '---####0.2####---'.length);
                    const completeDataLength = Buffer.byteLength(completeData, 'utf8'); // 计算接收到的数据长度（字节数）

                    if (completeDataLength >= expectedLength) {
                        // 数据完整，处理数据
                        const jsonData = completeData.slice(0, expectedLength); // 获取完整的JSON数据
                        buffer = buffer.slice(index + '---####0.2####---'.length + expectedLength); // 清理缓冲区
                        console.log(`Received complete data: ${jsonData}`);
                        event.reply('server-data-callback', jsonData);

                        // 重置状态以等待下一个数据包
                        expectedLength = 0;
                        lengthPrefixReceived = false;
                    }
                }
            }
            // event.reply('server-data-callback', data.toString());
            clearTimeout(id);
        });
        devClient.on('timeout', () => {
            console.log('Connection timed out');
            devClient.destroy();
            reject(new Error('Connection remote device timed out')); // 连接超时
            event.reply('conn-result', 'failed to connect');
            devClientIP = '';
        });
        devClient.on('error', (error) => {
            console.log(`receive error from remote device \n${error}`)
            resolve(false);
            event.reply('conn-result', 'failed to connect');
            devClientIP = '';
        });
        devClient.on('close', () => {
            console.log('close tcp connect successfully')
            exec("taskkill /IM com2tcp.exe /F");
            devClientIP = '';
        });
    });
}

// 测试网关设备是否在线
function pingDevice(ip, event) {
    const pingCommand = `ping`;
    const connProcess = spawn(pingCommand, [ip]);
    let already = true;
    connProcess.stdout.on('data', (data) => {
        const output = iconvLite.decode(data, 'GBK');
        const regex = /来自 (\d+\.\d+\.\d+\.\d+) 的回复: 字节=(\d+) 时间=(\d+)ms TTL=(\d+)/;
        const match = output.match(regex);
        if (match) {
            event.reply('ping-callback', `${ip}-0`);
            if (ip === devClientIP && already) {
                already = false;
                const requestPortSet = {
                    "cmd": 248
                };
                sentData(JSON.stringify(requestPortSet), devClient);
            }
        }
        const failRegex = /无法访问目标主机/;
        if (output.match(failRegex)) {
            event.reply('ping-callback', `${ip}-1`);
        }
        console.log(`stdout: ${output}`)
    });
    connProcess.stderr.on('data', (data) => {
        const output = iconvLite.decode(data, 'GBK');
        console.error(`stderr: ${output}`);
    });
    // 监听子进程结束事件
    connProcess.on('close', (code) => {
        console.log(`connection process exited with code ${code}`);
        if (code === 1) event.reply('ping-callback', `${ip}-1`);
        // const stringCode = code.toString();
    });
}
// 整个代码实现了一个功能丰富的 Electron 应用，涉及到网络通信、进程管理、IPC 通信、自动更新等多个方面。
// 代码结构清晰，使用了许多现代 JavaScript 特性，如 async/await、Promise、模块化等，使得代码易于维护和扩展。

